
package com.heimali.happyreader.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.heimali.happyreader.R;
import com.heimali.happyreader.utils.Utils;

import java.util.Date;

public class PullToRefreshListView extends ListView {

    public final static String TAG = "PullToRefreshListView";

    // 松开刷新标志
    private final static int RELEASE_TO_REFRESH = 0;

    // 下拉刷新标志
    private final static int PULL_TO_REFRESH = 1;

    // 正在刷新标志
    private final static int REFRESHING = 2;

    // 刷新完成标志
    private final static int DONE = 3;

    private LayoutInflater inflater;

    private LinearLayout headView;

    private TextView tipsTextview;

    private TextView lastUpdatedTextView;

    private ImageView arrowImageView;

    private ProgressBar progressBar;

    // 用来设置箭头图标动画效果
    private RotateAnimation animation;

    private RotateAnimation reverseAnimation;

    // 用于保证startY的值在一个完整的touch事件中只被记录一次
    private boolean isRecored;

    //	private int headContentWidth;

    private int headContentHeight;

    private int startY;

    private int firstItemIndex;
    
    private int lastItemIndex = 0;

    private int state;

    private boolean isBack;

    public OnRefreshListener refreshListener;

    public PullToRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {

        inflater = LayoutInflater.from(context);
        headView = (LinearLayout) inflater.inflate(R.layout.pull_to_refresh_header, null);

        arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);
        arrowImageView.setMinimumWidth(50);
        arrowImageView.setMinimumHeight(50);
        progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
        tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
        lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);

        measureView(headView);

        headContentHeight = headView.getMeasuredHeight();
        //		headContentWidth = headView.getMeasuredWidth();

        headView.setPadding(0, -1 * headContentHeight, 0, 0);
        headView.invalidate();

        addHeaderView(headView);
        setOnScrollListener(new ListViewScrollListener());

        animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        animation.setInterpolator(new LinearInterpolator());
        animation.setDuration(500);
        animation.setFillAfter(true);

        reverseAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        reverseAnimation.setInterpolator(new LinearInterpolator());
        reverseAnimation.setDuration(500);
        reverseAnimation.setFillAfter(true);
    }

    class ListViewScrollListener implements OnScrollListener {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (OnScrollListener.SCROLL_STATE_IDLE == scrollState) {
                if (lastItemIndex == view.getAdapter().getCount() && refreshListener != null) {
                   refreshListener.loadNextPage();
                }
            }
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            firstItemIndex = firstVisibleItem;
            lastItemIndex = firstVisibleItem + visibleItemCount;
        }
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (firstItemIndex == 0 && !isRecored) {
                    startY = (int) event.getY();
                    isRecored = true;
                }
                break;

            case MotionEvent.ACTION_UP:
                if (state != REFRESHING) {
                    if (state == DONE) {
                    }
                    if (state == PULL_TO_REFRESH) {
                        state = DONE;
                        changeHeaderViewByState();
                    }
                    if (state == RELEASE_TO_REFRESH) {
                        state = REFRESHING;
                        changeHeaderViewByState();
                        refresh();
                    }
                }

                isRecored = false;
                isBack = false;

                break;

            case MotionEvent.ACTION_MOVE:
                int tempY = (int) event.getY();
                if (!isRecored && firstItemIndex == 0) {
                    isRecored = true;
                    startY = tempY;
                }
                if (state != REFRESHING && isRecored) {
                    // 可以松开刷新了
                    if (state == RELEASE_TO_REFRESH) {
                        // 往上推，推到屏幕足够掩盖head的程度，但还没有全部掩盖
                        if ((tempY - startY < headContentHeight) && (tempY - startY) > 0) {
                            state = PULL_TO_REFRESH;
                            changeHeaderViewByState();
                        }
                        // 一下子推到顶
                        else if (tempY - startY <= 0) {
                            state = DONE;
                            changeHeaderViewByState();
                        }
                        // 往下拉，或者还没有上推到屏幕顶部掩盖head
                        else {
                            // 不用进行特别的操作，只用更新paddingTop的值就行了
                        }
                    }
                    // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
                    if (state == PULL_TO_REFRESH) {
                        // 下拉到可以进入RELEASE_TO_REFRESH的状态
                        if (tempY - startY >= headContentHeight) {
                            state = RELEASE_TO_REFRESH;
                            isBack = true;
                            changeHeaderViewByState();
                        }
                        // 上推到顶了
                        else if (tempY - startY <= 0) {
                            state = DONE;
                            changeHeaderViewByState();
                        }
                    }

                    // done状态下
                    if (state == DONE) {
                        if (tempY - startY > 0) {
                            state = PULL_TO_REFRESH;
                            changeHeaderViewByState();
                        }
                    }

                    // 更新headView的size
                    if (state == PULL_TO_REFRESH) {
                        headView.setPadding(0, -1 * headContentHeight + (tempY - startY), 0, 0);
                        headView.invalidate();
                    }

                    // 更新headView的paddingTop
                    if (state == RELEASE_TO_REFRESH) {
                        int newY = tempY - startY - headContentHeight;
                        newY = newY > headContentHeight * 1.5 ? (int) (headContentHeight * 1.5) : newY;
                        headView.setPadding(0, newY, 0, 0);
                        headView.invalidate();
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    // 当状态改变时候，调用该方法，以更新界面
    private void changeHeaderViewByState() {
        switch (state) {
            case RELEASE_TO_REFRESH:

                arrowImageView.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);
                tipsTextview.setVisibility(View.VISIBLE);
                lastUpdatedTextView.setVisibility(View.VISIBLE);

                arrowImageView.clearAnimation();
                arrowImageView.startAnimation(animation);

                tipsTextview.setText(R.string.pull_to_refresh_release_label);
                break;
            case PULL_TO_REFRESH:

                progressBar.setVisibility(View.GONE);
                tipsTextview.setVisibility(View.VISIBLE);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.VISIBLE);
                if (isBack) {
                    isBack = false;
                    arrowImageView.clearAnimation();
                    arrowImageView.startAnimation(reverseAnimation);

                    tipsTextview.setText(R.string.pull_to_refresh_pull_label);
                } else {
                    tipsTextview.setText(R.string.pull_to_refresh_pull_label);
                }
                break;

            case REFRESHING:

                headView.setPadding(0, 0, 0, 0);
                headView.invalidate();

                progressBar.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.GONE);
                tipsTextview.setText(R.string.pull_to_refresh_refreshing_label);
                lastUpdatedTextView.setVisibility(View.GONE);
                break;
            case DONE:
                headView.setPadding(0, -1 * headContentHeight, 0, 0);
                headView.invalidate();

                progressBar.setVisibility(View.GONE);
                arrowImageView.clearAnimation();
                // 此处更换图标
                arrowImageView.setImageResource(R.drawable.ic_pulltorefresh_arrow);

                tipsTextview.setText(R.string.pull_to_refresh_pull_label);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                break;
        }
    }

    public void setOnRefreshListener(OnRefreshListener refreshListener) {
        this.refreshListener = refreshListener;
    }

    public interface OnRefreshListener {
        public void refresh();

        public void loadNextPage();
    }

    public void refreshComplete() {
        state = DONE;
        lastUpdatedTextView.setText(String.format(getResources().getString(R.string.pull_to_refresh_last_time,
                Utils.DATE_FORMAT_3.format(new Date()))));
        changeHeaderViewByState();
    }

    private void refresh() {
        if (refreshListener != null) {
            refreshListener.refresh();
        }
    }

    // 此处是“估计”headView的width以及height
    @SuppressWarnings("deprecation")
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

}
